﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CILADA.Engine
{
    public class AssemblyReference : IComparable
    {
        private string _from;
        private string _to;

        public string From
        {
            get{
                return _from;
            }
            set
            {
                _from = ProcessAssemblyName(value);
            }
        }
        public string To
        {
            get
            {
                return _to;
            }
            set
            {
                _to = ProcessAssemblyName(value);
            }
        }
        public string Type { get; set; }
        public string Method { get; set; }
        public bool IsRuntimeDependency { get; set; }

        public AssemblyReference()
        {
            _from = null;
            _to = null;
            this.Method = null;
            this.Type = null;
            this.IsRuntimeDependency = false;
        }

        public AssemblyReference(string from, string to)
        {
            this.From = from;
            this.To = to;
            this.Method = null;
            this.Type = null;
            this.IsRuntimeDependency = false;
        }

        public AssemblyReference(string from, string to, string type)
        {
            this.From = from;
            this.To = to;
            this.Method = null;
            this.Type = type;
            this.IsRuntimeDependency = false;
        }

        private string ProcessAssemblyName(string name)
        {
            if (name == null)
            {
                return null;
            }
            else
            {
                if (name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
                {
                    return name.Substring(0, name.Length - 4);
                }
                else
                {
                    return name;
                }
            }
        }

        public override bool Equals(object obj)
        {
            if (obj is AssemblyReference)
            {
                AssemblyReference other = obj as AssemblyReference;
                return (this.From.Equals(other.From) && this.To.Equals(other.To));
            }
            return false;
        }

        public override int GetHashCode()
        {
            return To.GetHashCode() + From.GetHashCode();
        }

        public override string ToString()
        {
            string dep = "Dependency from " + From + " to " + To;
            if (this.Type != null)
            {
                dep += " on type " + this.Type;
            }
            if (this.Method != null)
            {
                dep += " caused by method " + this.Method;
            }
            return dep;
        }

        #region IComparable Members

        public virtual int CompareTo(object obj)
        {
            AssemblyReference other = obj as AssemblyReference;

            if (From != null)
            {
                int compFrom = this.From.CompareTo(other.From);
                if (compFrom != 0)
                {
                    return compFrom;
                }
            }

            if (To != null)
            {
                int compTo = this.To.CompareTo(other.To);
                if (compTo != 0)
                {
                    return compTo;
                }
            }

            return 0;
        }

        #endregion
    }
}
